package controllers;

import play.*;
import play.mvc.*;

import java.util.*;

import org.apache.commons.mail.EmailException;

import models.*;

/**
 * Topics Controller that links the views of the topic and the model class Topic
 * 
 * @author Nesreen elgohary
 * 
 */
public class Topics extends Controller {

	public static Long topicIdOne;
	/**
	 * renders a HTML page that is connected in its view with the createTopic
	 * method that takes the input parameters for creating a topic in a certain
	 * entity
	 * 
	 * @param entityId
	 *            id of the entity that the topic will be posted on
	 * @author Nesreen elgohary
	 */
	public static void topicPosting(Long entityId) {

		render(entityId);
	}

	/**
	 * renders a HTML page that takes as a parameter the entity id of the entity
	 * that it will be posted on and then gets the user from the session and
	 * then creates the topic, notifies the entity's subscriber and then pass
	 * the topic to showTopic() that displays the topic
	 * 
	 * When the user posts a new topic his contribution counter increases by 1
	 * 
	 * deletes the topic request, in case the topic was created through a
	 * request by an idea developer
	 * 
	 * @param entityId
	 *            id of the entity the topic will be posted on
	 * @param requestId
	 *            the topic request id that will be needed to delete the topic
	 *            request if exists.
	 * @author Nesreen elgohary
	 * @author Heba Khattab
	 * @author Shahir El Faramawy
	 */

	public static void createTopic(Long entityId, Long requestId) {

		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Entities entity = Entities.findById(entityId);
		String title = params.get("topic.title");
		String description = params.get("topic.body");
		Topic topic = new Topic(description, user, entity, title);
		topic.save();
		String details = ", the organizer has created a new topic called "
				+ topic.title + " topic in entity called " + entity.entityName;
		user.sendNotificationWithType(details, entity.subscribers, "Topic",
				topic.id);
		Long topicId = topic.id;
		user.contributionCounter++;
		user.save();
		if (requestId != null) {
			Request requestTopic = Request.findById(requestId);
			requestTopic.delete();
		}
		showTopic(topicId);
		render(entityId);
	}

	/**
	 * takes the entity id, and from the entity calls method topicsWithNoIdeas
	 * that get a list of topics that have no ideas and renders them and the
	 * user in the session
	 * 
	 * @param entityId
	 *            id of the entity
	 * @author Nesreen elgohary
	 */
	public static void topicsWithNoIdeas(Long entityId) {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Entities entity = Entities.findById(entityId);
		List<Topic> allTopics = entity.topicsWithNoIdeas();
		Permission permission = User.userPermissionInOrganization(user.id,
				entity.organization.id);
		String role = permission.aUserType;
		boolean permit = false;
		String userType = role;

		if (userType.matches("organizationLead")
				|| userType.matches("organizer")
				|| user.email.matches("admin@admin.com")) {
			permit = true;
		}

		else {
			permit = false;
		}
		render(allTopics, user, entityId, permit);
	}

	/**
	 * takes topic id as an input then gets the topic, deletes it and notifies
	 * the subscribers and connects with an HTML page that has a confirmation
	 * for the deletion
	 * 
	 * @param topicId
	 *            id of the topic that will be deleted
	 * @author Nesreen elgohary
	 * @throws EmailException
	 */
	public static void topicDeleted(Long topicId) throws EmailException {
		try{
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Topic topic = Topic.findById(topicId);
		Entities entity = topic.entity;

		String details = ", the organizer has deleted " + topic.title
				+ " topic in entity called " + entity.entityName;

		if (topic.hasIdeas == false) {
			for (int counter = 0; counter < topic.subscribers.size(); counter++) {
				Email mail = new Email(user.email,
						topic.subscribers.get(counter).email,
						"deleted a topic", "" + user.name
								+ " deleted the topic " + topic.title + "");
				mail.sendEmail();
			}
			user.sendNotificationWithType(details, topic.subscribers, "Entity",
					entity.id);
			user.save();
			if (!topic.subscribers.isEmpty()) {
				for (int counter = 0; counter < topic.subscribers.size(); counter++) {
					topic.subscribers.get(counter).topic.remove(topic);
					topic.subscribers.get(counter).save();
				}
			}
			if (!topic.subscribers.isEmpty()) {
				for (int counter = 0; counter < topic.subscribers.size(); counter++) {
					topic.subscribers.get(counter).topicSubscribed
							.remove(topic);
					topic.subscribers.get(counter).save();
					topic.save();
				}
			}
			if (!topic.tags.isEmpty()) {
				for (int counter = 0; counter < topic.tags.size(); counter++) {
					topic.tags.get(counter).Topics.remove(topic);
					topic.tags.get(counter).save();
				}
			}
			if (!topic.relationList.isEmpty()) {
				for (int counter = 0; counter < topic.relationList.size(); counter++) {
					topic.relationList.get(counter).topicList.remove(topic);
					topic.relationList.get(counter).save();
				}
			}
			if (!topic.spamReporters.isEmpty()) {
				for (int counter = 0; counter < topic.spamReporters.size(); counter++) {
					topic.spamReporters.get(counter).topic.remove(topic);
					topic.spamReporters.get(counter).save();
				}
			}
			topic.author.topic.remove(topic);
			topic.author.contributionCounter--;
			topic.delete();

			showDeleteMsg(entity.id);
		}}
		 catch (NullPointerException error) {
				Requests.contentNotFound();
			}
	}

	/**
	 * displays a page with the deletion message in case a topic was
	 * successfully deleted
	 * 
	 * @author Nesreen elgohary
	 */
	public static void showDeleteMsg(Long entityId) {
		render(entityId);
	}

	/**
	 * takes the topic id as an input to be able to display it
	 * 
	 * render the boolean authorized and it checks if the logged in user is an
	 * organization lead or organizer to be able to lock and unlock topic @author
	 * Mohamed Abdel Kader
	 * 
	 * checks if the user marked this topic as spam or not.
	 * 
	 * it renders the value of the tags that the topic is untagged in
	 * 
	 * @author Shahir El Faramawy
	 * 
	 * @param topicId
	 *            id of the topic that will be shown
	 * @author Ghada Abu Shady
	 * @author Nesreen elgohary
	 */
	public static void showTopic(Long topicId) {

		topicIdOne=topicId;
		
			String userIdString = session.get("userId");
			if (userIdString == null) {
				Home.home(null, null, "Please Login");
			}
			Long userId = Long.parseLong(userIdString);
			User user = User.findById(userId);

		
		Topic topic = Topic.findById(topicId);
		boolean inSubscriber = topic.userinSubscribers(user);
		topic.save();

		Entities entity = topic.entity;

		Organization organization = entity.organization;

		List<User> entityOrganizer = entity.entityOrganizers;

		boolean authorized = false;
		Permission permission = User.userPermissionInOrganization(user.id,
				entity.organization.id);
		String role = permission.aUserType;
		boolean permit = false;
		String userType = role;

		if (userType.matches("organizationLead")
				|| userType.matches("organizer")
				|| user.email.matches("admin@admin.com")) {
			permit = true;
		}

		else {
			permit = false;
		}

		if (organization.lead == user) {
			authorized = true;
		} else {
			for (int counter = 0; counter < entityOrganizer.size(); counter++) {

				if (entityOrganizer.get(counter) == user) {
					authorized = true;
				} else {
					authorized = false;
				}

			}
		}
		boolean isSpammed = false;
		for (int counter = 0; counter < topic.spamReporters.size(); counter++) {
			if (user.id == topic.spamReporters.get(counter).id) {
				isSpammed = true;
			}
		}
		List<Tag> tagsTopicNotTaggedIn = new ArrayList();
		for (int counter = 0; counter < topic.entity.organization.tags.size(); counter++) {
			boolean found = true;
			for (int secondCounter = 0; secondCounter < topic.tags.size(); secondCounter++) {
				if (topic.tags.get(secondCounter).id == topic.entity.organization.tags
						.get(counter).id) {
					found = false;
					break;
				}

			}

			String tagString = "tttttttttttttttttt" + topic.id;
			render(topic, user, authorized, inSubscriber, isSpammed,
					tagsTopicNotTaggedIn, tagString,permit,topic.ideas);
		

			if (found == true) {
				tagsTopicNotTaggedIn.add(topic.entity.organization.tags
						.get(counter));
			}
		}
		List<Idea>idea=topic.ideas;
		String tagString = "t" + topic.id;
		render(topic, user, authorized, inSubscriber, isSpammed,
				tagsTopicNotTaggedIn, tagString, permit,idea);

	}

	/**
	 * takes the entity id as an input to get the entity and then get the
	 * entity's topics list and then display the title of each topic in the
	 * specified entity
	 * 
	 * @param entityId
	 *            id of the entity that its topics will be reviewed
	 * @author Nesreen elgohary
	 */
	public static void listOfAllTopics(Long entityId) {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
        System.out.println(user.email+"tozzzzzz");
		Entities entity = Entities.findById(entityId);
		 System.out.println(entityId+"kerkerker");
		List<Topic> allTopics = entity.topics;
		Permission permission = User.userPermissionInOrganization(user.id,
				entity.organization.id);
        System.out.println(permission.aUserType);
		String role = permission.aUserType;
		boolean authorized = false;
		String userType = role;

		if (userType.matches("organizationLead")
				|| userType.matches("organizer")
				|| user.email.matches("admin@admin.com")) {
			authorized = true;
		}

		else {
			authorized = false;
		}
		render(allTopics, entityId, user, authorized);
	}

	/**
	 * takes the entity id as an input to get the entity and then get the
	 * entity's hidden topics list and then display the title of each topic in
	 * the specified entity
	 * 
	 * @param entityId
	 *            id of the entity that its hidden topics will be reviewed
	 * @author Nesreen elgohary
	 */
	public static void listOfHiddenTopics(Long entityId) {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Entities entity = Entities.findById(entityId);
		List<Topic> allTopics = entity.listOfHiddenTopics();
		Permission permission = User.userPermissionInOrganization(user.id,
				entity.organization.id);
		String role = permission.aUserType;
		boolean permit = false;
		String userType = role;

		if (userType.matches("organizationLead")
				|| userType.matches("organizer")
				|| user.email.matches("admin@admin.com")) {
			permit = true;
		}

		else {
			permit = false;
		}
		render(allTopics, entityId, user, permit);
	}

	/**
	 * takes the topic id as an input to get the topic and then change the hide
	 * status to true and saves in the database, notifies the subscribers of the
	 * topic and connects with an HTML page to show all topics
	 * 
	 * @param topicId
	 *            id of the topic that will be hidden
	 * @author Nesreen elgohary
	 * @throws EmailException
	 */
	public static void hideTopic(Long topicId)
			throws EmailException {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Topic topic = Topic.findById(topicId);
		Entities entity = topic.entity;
		String justificationNote = params.get("Note");
		String note= " for the following reason: " + justificationNote;
		String details = ", the organizer has hided " + topic.title
				+ " topic in entity called " + entity.entityName
				+note;

		topic.hide = true;
		topic.save();
		user.sendNotificationWithType(details, topic.subscribers, "Entity",
				entity.id);
		user.save();
		
		for (int counter = 0; counter < topic.subscribers.size(); counter++) {
			Email mail = new Email(user.email,
					topic.subscribers.get(counter).email, "hided a topic", ""
							+ user.name + " hided the topic " + topic.title
							+ note);
			mail.sendEmail();
		}
		
		listOfAllTopics(entity.id);
	}

	/**
	 * takes the topic id as an input to get the topic and then change the hide
	 * status to false and saves in the database, notifies the subscribers of
	 * the topic and connects with an HTML page to show all hided topics
	 * 
	 * @param topicId
	 *            id of the topic that will be not hidden
	 * @author Nesreen elgohary
	 * @throws EmailException
	 */
	public static void unhideTopic(Long topicId) throws EmailException {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Topic topic = Topic.findById(topicId);
		Entities entity = topic.entity;
		
		String details = ", the organizer has unhided " + topic.title
				+ " topic in entity called " + entity.entityName;

		topic.hide = false;
		topic.save();
		for (int counter = 0; counter < topic.subscribers.size(); counter++) {
			Email mail = new Email(user.email,
					topic.subscribers.get(counter).email, "unhided a topic", ""
							+ user.name + " unhided the topic " + topic.title
							+ "");
			mail.sendEmail();
		}
		user.sendNotificationWithType(details, topic.subscribers, "Topic",
				topic.id);
		user.save();
		listOfHiddenTopics(entity.id);
	}

	
	
	/**
	 * renders a HTML page that takes as a parameter the topic id of the topic
	 * and entityId then executes and closes it if the user is the author of
	 * this topic.
	 * 
	 * @param topicId
	 *            The topic id that we want to execute it
	 * @param entityId
	 * 
	 *            it's the id of the entity in which this topic is posted
	 * @author youstina galal
	 */
                         
	
	public static void showTopicIdeasForExecution(Long topicId){
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		System.out.println(topicId+"lololololo");
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		System.out.println(user.name+"dah:S");
		topicIdOne=topicId;
		System.out.println(topicId+"hhhahahaha");
		Topic topic=Topic.findById(topicId);
		List<Idea>idea=topic.ideas;
		System.out.println(topic.ideas.size());
		render(idea,user,topic);
		
	}

	
	
	
	public static void selectAllTopicIdeaExecuted() {
		try {

			Topic topic = Topic.findById(topicIdOne);
			Organization orgainzation = topic.entity.organization;
			System.out.println(orgainzation.id);
			Entities entity = topic.entity;
			System.out.println(entity.id+"entittttttttt");
			System.out.println(topicIdOne + "topicIDDDD");
			String input = params.get("box");
			String idRetrieve = "";
			if(input.length()>1){
				System.out.println(input);
			for (int counter = 0; counter <input.length(); counter++) {
				
					if (input.charAt(counter) >= '0'
							&& input.charAt(counter) <= '9') {
						idRetrieve += input.charAt(counter);}}
			
				Long id = Long.parseLong(idRetrieve);
				Idea idea = Idea.findById(id);
			
				System.out.println(idea.body+"totoooooo");
				String idString = session.get("userId");
				if (idString == null) {
					Home.home(null, null, "Please Login");
				}
				Long userId = Long.parseLong(idString);
				User userOrganizer = User.findById(userId);
				
				if (userOrganizer.email == topic.author.email) {
					System.out.println(topic.author.email+"youstina");
					topic.executeAndPromote(idea);
					topic.save();
					listOfAllTopics(entity.id);
				} else {
					if (userOrganizer.email == topic.entity.organization.lead.email) {
						System.out.println(topic.author.email+"youstina");
						topic.executeAndPromote(idea);
						topic.save();
						listOfAllTopics(entity.id);
					}
				}
			}else{
				PostingIdea.showTopicIdeas(topicIdOne);
				
			}	
				
			

		} catch (NullPointerException error) {
			Requests.contentNotFound();
		}

	}
	



	/**
	 * takes a topic id, retrieves the topic and the User that marked the topic
	 * as spammed and will set the topic to spammed using the spamTopic method
	 * from the model.
	 * 
	 * @param id
	 *            The topic id that got spammed.
	 * @author Shahir El Faramawy
	 */
	public static void showTopicSpam(Long id) throws EmailException {
		String temp = session.get("userId");
		if (temp == null) {
			Home.home(null, null, "Please Login");
		}
		Long idTemp = Long.parseLong(temp);
		User spamer = User.findById(idTemp);
		Topic spammed = Topic.findById(id);
		spammed.spamTopic(spamer);
		showTopic(id);

	}

	/**
	 * takes an input entity id that the topic is posted on and id of draft that
	 * will be published and opens a page that the user can edit the draft
	 * before being publihed then save it as a topic
	 * 
	 * @param entityId
	 *            id of entity that draft will be posted to
	 * @param draftId
	 *            id of draft that will be posted
	 * 
	 * @author Heba Khattab
	 */
	public static void publishDraftAsTopic(Long entityId, Long draftId) {
		boolean canPublish;
		Entities entity = Entities.findById(entityId);
		String id = session.get("userId");
		if (id == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(id);
		User user = User.findById(userId);
		Permission permission = User.userPermissionInOrganization(user.id,
				entity.organization.id);
		String role = permission.aUserType;
		if (role.matches("organizationLead")) {
			canPublish = true;
		}

		else {
			canPublish = false;
		}
		Draft draft = Draft.findById(draftId);
		render(entityId, draft, canPublish);
	}

	/**
	 * adds a user to subscriber list
	 * 
	 * @author Sara Assem
	 * @param Long
	 *            id id of the tag
	 */
	public static void addSubscriber(Long topicid) {
		Topic topic = Topic.findById(topicid);
		String idstring = session.get("userId");
		Long userid = Long.parseLong(idstring);
		User user = User.findById(userid);
		user.topicSubscribed.add(topic);
		topic.addUserToSubscribers(user);
		topic.save();
		user.save();
		showTopic(topicid);

	}

	/**
	 * removes user from subscriber list
	 * 
	 * @author Sara Assem
	 * @param Long
	 *            id id of the tag
	 */

	public static void removeSubscriber(Long topicid) {
		Topic topic = Topic.findById(topicid);
		String idstring = session.get("userId");
		Long userid = Long.parseLong(idstring);
		User user = User.findById(userid);
		user.topicSubscribed.remove(topic);
		topic.removeUserFromSubscribers(user);
		topic.save();
		user.save();
		showTopic(topicid);

	}

	/**
	 * Locks a topic so it can not be accessible to make relations with that
	 * take an id and find an topic by this id
	 * 
	 * @param id
	 *            id of the topic to be locked then call a method in the model
	 *            to lock this topic
	 * @author Mohamed Abdel Kader
	 */

	public static void lockTopic(Long topicId) {

		Topic topic = Topic.findById(topicId);
		topic.lockTopic(topic);

	}

	/**
	 * unlocks a topic so it can be accessible to make relations with
	 * 
	 * 
	 * @param id
	 *            id of the topic to be unlocked then call a method in the model
	 *            to unlock this topic
	 * @author Mohamed Abdel Kader
	 */

	public static void unlockTopic(Long topicId) {

		Topic topic = Topic.findById(topicId);
		topic.unlockTopic(topic);

	}
	/**
	 * displays a page where the organizer can enter a justification Note for
	 * hiding a topic
	 * 
	 * @param topicId
	 *            id of topic to be hidden
	 * 
	 * @author Nesreen elGohary
	 */
	public static void justificationNote(Long topicId) {
		Topic topic=Topic.findById(topicId);
		String justificationNote = params.get("Note");
		render(topic, justificationNote);
	}
	public static void showIdeaExecuted(Long ideaId){
		Idea idea = Idea.findById(ideaId);
		render(idea);
	}

}
